package com.asiainfo.dacp.datastash.broker.core.vo;

import com.asiainfo.dacp.core.BeanFactory;
import com.asiainfo.dacp.datastash.broker.core.StashUnitProcessModel;
import com.asiainfo.dacp.datastash.broker.core.enums.UnitTaskStateEnum;
import com.asiainfo.dacp.datastash.broker.flow.core.domain.Flow;
import com.asiainfo.dacp.util.SimpleKey;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 *
 * stash的分片信息值对象
 *
 * @author MeiKefu
 * @date 2017-11-21
 */
@Data
@NoArgsConstructor
public class StashUnitTask implements Serializable {

    private String taskProcId = SimpleKey.genUuid(32);///分片订单号

    private String unitProcId;//订单号

    private String taskType;

    private List<String> preTaskProcIds = new ArrayList<>();//提供依赖的id，判断是否前置都到达

    private List<String> nextTaskProcIds = new ArrayList<>();

    private List<StashUnitStep> taskSteps = new ArrayList<>();//子任务的步骤

    private String brokerId;
    
    private String brokerIp;

    private String unitCode;

    private String batchNo;

    private List<Map<String,String>> taskContent;

    private UnitTaskStateEnum taskState = UnitTaskStateEnum.INIT;//等待分配，等待执行，执行中，成功

    public String buildSerNo(){
    	return String.format("%s-%s-%s", unitCode, unitProcId, taskProcId);
    }
    
    public void cleanPreTask(){
    	this.preTaskProcIds = new ArrayList<>();
    }
    public void cleanNextTask(){
    	this.nextTaskProcIds = new ArrayList<>();
    }
    
    public void addTaskStep(StashUnitStep step){
    	this.taskSteps.add(step);
    }
    
    public void addPreTaskProcId(String id){
    	this.preTaskProcIds.add(id);
    }
    
    public void addPreTask(StashUnitTask task){
    	this.preTaskProcIds.add(task.getTaskProcId());
    }
    
    public void addNextTaskProcId(String id){
    	this.nextTaskProcIds.add(id);
    }
    
    public void addNextTask(StashUnitTask task){
    	this.nextTaskProcIds.add(task.getTaskProcId());
    }
    
    public boolean hasNext(){
    	return this.nextTaskProcIds.size() > 0;
    }
    
    public String nextProcId(){
    	if(hasNext()){
    		return this.nextTaskProcIds.get(0);
    	}else{
    		return null;
    	}
    }
    public List<String> nextProcIds(){
    	return this.nextTaskProcIds;
    }
    
    @JsonIgnore
    public static StashUnitTask NULL = new StashUnitTask("NULL","NULL","",null);

    public StashUnitTask(String taskType, StashUnit redisUnit){
    	this(redisUnit.getUnitProcId(), taskType,
				redisUnit.getUnitCode(), redisUnit.getBatchNo());
    }
    
    public StashUnitTask(String taskType, Flow flow){
    	this(flow.getSerNo(), taskType,
				flow.getUnitCode(), flow.getBatchNo());
    }
    
    public StashUnitTask(String unitProcId,String taskType, String unitCode, String batchNo){
        this.unitCode=unitCode;
        this.batchNo=batchNo;
        this.taskType = taskType;
        this.unitProcId = unitProcId;
    }

    public StashUnitTask(String unitProcId,String taskType, String unitCode, String batchNo, List<Map<String,String>> taskContent){
        this.unitCode=unitCode;
        this.batchNo=batchNo;
        this.unitProcId = unitProcId;
        this.taskType = taskType;
        this.taskContent = taskContent;
    }

    public void success(){
        StashUnitProcessModel stashUnitProcessModel = BeanFactory.getBean(StashUnitProcessModel.class);
        stashUnitProcessModel.updateUnitTaskState(taskProcId,UnitTaskStateEnum.SUCESS.value());
    }

    public void failed(){
        StashUnitProcessModel stashUnitProcessModel = BeanFactory.getBean(StashUnitProcessModel.class);
        stashUnitProcessModel.updateUnitTaskState(taskProcId,UnitTaskStateEnum.FAIL.value());
    }
    
    public void runnable(){
        StashUnitProcessModel stashUnitProcessModel = BeanFactory.getBean(StashUnitProcessModel.class);
        stashUnitProcessModel.updateUnitTaskState(taskProcId,UnitTaskStateEnum.RUNNABLE.value());
    }

    public void running(){
        StashUnitProcessModel stashUnitProcessModel = BeanFactory.getBean(StashUnitProcessModel.class);
        stashUnitProcessModel.updateUnitTaskState(taskProcId,UnitTaskStateEnum.RUNNING.value());
    }

    public void waiting(){
        StashUnitProcessModel stashUnitProcessModel = BeanFactory.getBean(StashUnitProcessModel.class);
        stashUnitProcessModel.updateUnitTaskState(taskProcId,UnitTaskStateEnum.BLOCKED_RELAY.value());
    }
}
